<?php 

// +----------------------------------------------------------------------

// | Fanwe 多语商城建站系统 (Build on ThinkPHP)

// +----------------------------------------------------------------------

// | Copyright (c) 2009 http://www.fanwe.com All rights reserved.

// +----------------------------------------------------------------------

// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )

// +----------------------------------------------------------------------

// | Author: 云淡风轻(97139915@qq.com)

// +----------------------------------------------------------------------
//数据库全库导出，导入的操作类

import("Think.Db.Db");

class SqlDump extends Think 

{

	private $db;

	private $max_size;  //分卷的最大文件大小

	public function __construct()

	{

		ini_set("memory_limit","256M");

		set_time_limit(0);

		$this->db = Db::getInstance();

		$this->max_size = fanweC("DB_VOL_MAXSIZE");

	}

    /**

     *  生成备份文件头部

     *

     * @access  public

     * @param   int     文件卷数

     *

     * @return  string  $str    备份文件头部

     */

    private function make_head($vol)

    {

        /* 系统信息 */

        $sys_info['os']         = PHP_OS;

        $sys_info['web_server'] = $_SERVER["SERVER_SOFTWARE"];

        $sys_info['php_ver']    = php_sapi_name();

        $sys_info['mysql_ver']  = mysql_get_server_info();

        $sys_info['date']       = toDate(gmtTime(),'Y-m-d H:i:s');



        $head = "-- fanwe SQL Dump Program\r\n".

                 "-- " . $sys_info['web_server'] . "\r\n".

                 "-- \r\n".

                 "-- DATE : ".$sys_info["date"]."\r\n".

                 "-- MYSQL SERVER VERSION : ".$sys_info['mysql_ver']."\r\n".

                 "-- PHP VERSION : ".$sys_info['php_ver']."\r\n".

                 "-- Vol : ".$vol."\r\n\r\n\r\n";

        

        return $head;

    }

	public function get_all_table()
	{
		
		 $tables_all = $this->db->getTables(); 
		 $tables = array();

		 foreach($tables_all as $table)
		 {

		 	if(preg_match("/".C('DB_PREFIX')."/",$table))

		 	{

		 		array_push($tables,$table);

		 	}

		 }
		 return $tables;
	}    


    /**

     * 分卷导出

     *

     * @return boolean

     */

	public function dump($tables_1='',$dumptime_1='')

	{
		
		if($tables_1==''){
		 $tables_all = $this->db->getTables(); 
		 $tables = array();

		 foreach($tables_all as $table)
		 {

		 	if(preg_match("/".C('DB_PREFIX')."/",$table))

		 	{

		 		array_push($tables,$table);

		 	}

		 }
		}
		else
		{
			$tables=$tables_1;
		}
		 
		
		 $vol = 1;

		 $dumpsql_vol = $this->make_head($vol);  //每一卷的SQL语句

		 $dumpfile = "";
		$dumptime = gmtTime();
		 	if($dumptime_1==''){
		 $dumptime_1 = gmtTime();  //当前导出的时间
		}else{
		 $dumptime_1 = $dumptime_1;
		}
		

		 $filepath =  A("Fanwe")->getRealPath()."/public/db_backup/";   //导出的目录

		 $iserror = false;

		 

		 foreach ($tables as $key=>$tbname)
		 {  

		 	 $modelname=str_replace(C('DB_PREFIX'),'',$tbname); 	 

		 	 $tbname_o = $tbname;

		 	 $tbname = 	str_replace(C('DB_PREFIX'),'%DB_PREFIX%',$tbname); 

			 $dumpsql_vol .= "DROP TABLE IF EXISTS `$tbname`;\r\n";  //用于表结构导出处理的Sql语句

			 

		 	 $tmp_arr = $this->db->query("SHOW CREATE TABLE `$tbname_o`");

		     $tmp_sql = $tmp_arr[0]['Create Table'].";\r\n";

		     $tmp_sql  = str_replace(C('DB_PREFIX'),'%DB_PREFIX%',$tmp_sql); 

			 $dumpsql_vol .= $tmp_sql;   //表结构语句处理结束

		 	 

		     $modelname = parse_name($modelname,1); 

		     $model=D($modelname);  

		     $tableData=$model->findAll();  //查询当前表的所有数据

			 

			 if($key==count($tables)-1 && count($tableData) == 0)

			 {

				 if($this->savefile($dumptime,$filepath,$vol,$dumpsql_vol,$dumptime_1))

				 	$vol++;

				 else

				 {

					return false;

				 }

			 }

			 else

			 {

				 foreach ($tableData as $row_num=>$row) 

				 {  

					 $dumpsql_row = "INSERT INTO `{$tbname}` VALUES (";   //用于每行数据插入的SQL脚本语句 

					 foreach($row as $col_value) 

					 {  

					   $dumpsql_row .="'".mysql_real_escape_string($col_value)."',";  

					 }  

					 $dumpsql_row=substr($dumpsql_row,0,-1);  //删除最后一个逗号

					 $dumpsql_row .= ");\r\n";  

					 $dumpsql_vol.= $dumpsql_row;  

					

					 //开始判断分卷长度

					 if(strlen($dumpsql_vol) > $this->max_size)

					 {

						//读取至最后一张表的最后一行

						if($this->savefile($dumptime,$filepath,$vol,$dumpsql_vol,$dumptime_1))

							$vol++;

						else

						 {

							return false;

						 }

						$dumpsql_vol = $this->make_head($vol);  //重新制作卷头

					 } 	

					 elseif($key==count($tables)-1 && $row_num==count($tableData)-1)

					 {

						//读取至最后一张表的最后一行

						if($this->savefile($dumptime,$filepath,$vol,$dumpsql_vol,$dumptime_1))

							$vol++;

						 else

						 {

							return false;

						 }

					 }	 	 

				 } 

			 }

		 }

		 

		 return true;

    }

	

	private function savefile($dumptime,$filepath,$k,$filestr,$name)

	{

		$filename =  $name."_".$k.".sql";  //导出的sql名

		$rs = file_put_contents($filepath.$filename,$filestr);

		if($rs==0)

		{

			//导出失败

			$i = 1;

			for ($i;$i <= $k;$i++)

			{

				@unlink($filepath.$dumptime."_".$i.".sql");

			}

			return false;

		}

		else

			return true;

	}

    

    

    /**

     * 恢复列表的备份

     *

     * @param array $filelist

     * @return string

     */

    public function restore($filelist)

    {

    	$filepath =  A("Fanwe")->getRealPath()."/public/db_backup/";   //导出的目录

    	foreach($filelist as $fileItem)

    	{

    		$sql = file_get_contents($filepath.$fileItem['filename']);

    		$sql = $this->remove_comment($sql);

    		$sql = trim($sql);

    		$sql = str_replace("\r", '', $sql);

       		$segmentSql = explode(";\n", $sql);

       		foreach($segmentSql as $itemSql)

       		{

       			if($itemSql!='')

       			{

	       			$itemSql = str_replace("%DB_PREFIX%",C('DB_PREFIX'),$itemSql);

	       			$this->db->query($itemSql);

	       			if($this->db->getError()!="")

	       			{

	        				return $this->db->getError();

	       			}

       			}

       		}

    	}

    	return "";

    }

    

    



    /**

     * 过滤SQL查询串中的注释。该方法只过滤SQL文件中独占一行或一块的那些注释。

     *

     * @access  public

     * @param   string      $sql        SQL查询串

     * @return  string      返回已过滤掉注释的SQL查询串。

     */

    private function remove_comment($sql)
    {

        /* 删除SQL行注释，行注释不匹配换行符 */

        $sql = preg_replace('/^\s*(?:--|#).*/m', '', $sql);



        /* 删除SQL块注释，匹配换行符，且为非贪婪匹配 */

        //$sql = preg_replace('/^\s*\/\*(?:.|\n)*\*\//m', '', $sql);

        $sql = preg_replace('/^\s*\/\*.*?\*\//ms', '', $sql);
        return $sql;

    }





}



?>